package com.linjacy.httpproject.aspect;

import com.alibaba.fastjson.JSON;
import com.linjacy.httpproject.annotation.NeedToEncrypt;
import com.linjacy.httpproject.exception.SystemErrorException;
import com.linjacy.httpproject.response.R;
import com.linjacy.httpproject.util.MD5Util;
import com.linjacy.httpproject.util.RSAUtil;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import javax.crypto.IllegalBlockSizeException;
import java.io.IOException;

@RestControllerAdvice
public class ExceptionDeal implements ResponseBodyAdvice {
    @ExceptionHandler(value = SystemErrorException.class)
    public R handleException(Exception e){
        return R.error(e.getMessage());
    }

    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public R handleMethodArgumentNotValidException(Exception e){
        MethodArgumentNotValidException e1 = (MethodArgumentNotValidException)e;
        return R.error(e1.getBindingResult().getFieldError().getDefaultMessage());
    }

    /**
     * 该方法决定了是否增强返回参数
     * @param methodParameter
     * @param aClass
     * @return
     */
    @Override
    public boolean supports(MethodParameter methodParameter, Class aClass) {
        NeedToEncrypt annotation = methodParameter.getMethod().getAnnotation(NeedToEncrypt.class);
        if(annotation == null){
            return false;
        }
        return true;
    }

    /**
     * 其中的body可以获取到返回数据
     * @param body
     * @param methodParameter
     * @param mediaType
     * @param aClass
     * @param serverHttpRequest
     * @param serverHttpResponse
     * @return
     */
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        try {
            return RSAUtil.rsaEncryptOAEP(JSON.toJSONString(body), RSAUtil.publicKey);
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return body;
    }
}
